/*
* @Author: z.p
* @Project: Zdotp
* @Date: 2025年01月18日
* @Description: 房间Actor的handler
*/
using Pb;
using Zdotp.Actor;
using Zdotp.Actor.Controller;
using Zdotp.Actor.Kcp;
using Zdotp.Actor.Packet;

namespace MultiGateServer.Actors;

public class MultiRoomEnterHandler : ActorController<MultiRoomActor, RoomEnterMessage>
{
    protected override void Run(MultiRoomActor actor, ActorSystem system, MessageInfo info, RoomEnterMessage data)
    {
        // 广播玩家进入游戏
        var players = actor.Players;
        var playerId = actor.GetNewPlayerId();
        players.Add(info.SessionId, new MultiRoomActor.Player(playerId, info.SessionId, info.SendActorId));
        actor.Logger.Info($"[playerEnter] Count : {players.Count}");
        actor.SendMessage<WriteMessage>(message =>
        {
            message.Data = ActorSystem.GetNetPacket(new DataPacket { Content = $"[broadcast] player {playerId} enter game success" });
        });
        
    }
}
public class MultiRoomLeaveHandler : ActorController<MultiRoomActor, RoomLeaveMessage>
{
    protected override void Run(MultiRoomActor actor, ActorSystem system, MessageInfo info, RoomLeaveMessage data)
    {
        var players = actor.Players;
        if (!players.TryGetValue(info.SessionId, out var player))
        {
            actor.Logger.Error($"[playerLeave] Session {info.SessionId} not exist");
            return;
        }
        // 广播玩家退出游戏
        actor.SendMessage<WriteMessage>(message =>
        {
            message.Data = ActorSystem.GetNetPacket(new DataPacket { Content = $"[broadcast] player {player.PlayerId} leave game success" });
        });
        players.Remove(player.SessionId);
        actor.Logger.Info($"[playerLeave] Count : {players.Count}");
    }
}
public class MultiRoomChatHandler : ActorController<MultiRoomActor, RoomChatMessage>
{
    protected override void Run(MultiRoomActor actor, ActorSystem system, MessageInfo info, RoomChatMessage data)
    {
        try
        {
            var players = actor.Players;
            var rawContent = data.Content;
            var isBroadcast = rawContent.All(c => c != '_');
            if (isBroadcast)
            {
                var bytes = ActorSystem.GetNetPacket(new DataPacket { Content = $"[broadcast] player {players[info.SessionId].PlayerId} say: {rawContent}" });
                actor.SendMessage<WriteMessage>(message => { message.Data = bytes; });
            }
            else
            {
                var playerId = -1;
                var content = string.Empty;
                for (var i = 0; i < rawContent.Length; i++)
                {
                    if (rawContent[i] != '_') continue;
                    var s = rawContent[..i];
                    playerId = int.Parse(s);
                    content = rawContent[(i + 1)..];
                    break;
                }

                if (playerId == -1)
                {
                    actor.Logger.Error($"[playerId == -1] Session {info.SessionId} send message error, content: {rawContent}");
                    return;
                }

                var player = players.Values.FirstOrDefault(currentPlayer => currentPlayer.PlayerId == playerId);
                if (player == null)
                {
                    actor.SendMessage<WriteMessage>(message =>
                    {
                        message.Data = ActorSystem.GetNetPacket(new DataPacket { Content = $"[unicast] player {playerId} not exist" });
                    }, info.SendActorId, info.SessionId);
                    return;
                }

                var res = $"[unicast] player {players[info.SessionId].PlayerId} say: [{content}] to player {playerId}!";
                // 给自己回复
                actor.SendMessage<WriteMessage>(message =>
                {
                    message.Data = ActorSystem.GetNetPacket(new DataPacket { Content = res });
                }, info.SendActorId, info.SessionId);
                
                // 给对方回复
                actor.SendMessage<WriteMessage>(message =>
                {
                    message.Data = ActorSystem.GetNetPacket(new DataPacket { Content = res });
                }, player.GateActorId, player.SessionId);
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}